package com.ketti.team;

import java.util.HashMap;

import android.app.TabActivity;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.View.OnLongClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.TabHost.TabSpec;

/***
 * Applicatoin : Android Editor
 * 
 * @author 
 * @since 		@version	@explain
 * ============================================================================
 * JaeGwang Ryu
 * 2010,04,23 	0.10	Create tab that height is height of text.
 * 2010,04,23	0.11	Apply background image for tab.
 * 2010,04,25	0.12	Create view that connected with tab.
 * 						And show this app_name and filename to application title.
 * KyungYul Kim
 * 2010,04,26	0.20	The text applied NewEditText that is customized
 * 						for JAVA keyword Auto-complete and Search function.
 * 2010,04,27	0.21	Create NEW class "SourceView" and cut out some UI codes,
 * 						put them into NEW XML file(source_view.xml)
 * 2010,04,28	0.22	Show line highlight, set filter for "/", "*"
 * 
 * 2010,04,29	0.21	add 6 items for option menu.
 * 
 * 2010,04,30	0.23	implemented 'go line'
 * 
 * 2010,05,02	0.24	refactoring(incomplete)
 * 
 * 2010,05,10	0.25	refactoring(simplify some method in NewEditText,
 * 						add some new features)
 * 
 * 2010,05,10	0.26	add features(do indent when "ENTER" button clicked)
 * 						, now we can access "/sdcard/source/" and 
 * 						read "*.java" file with "FileIO" class.
 * 
 * 2010,05,11	0.27	add small image under tab. add "Tab Menu" for each tab
 * 						(invoked when long clicked)
 * 
 * */

public class EditorActivity extends TabActivity implements TabHost.TabContentFactory
{
	// This is widget to have tabWidget.
	private TabHost mTabHost;
	// This is repository that have filename(tag of tab) and sourceView.
	private HashMap<String, View> mSourceView;			
	
	private InputMethodManager iputMethodManager;
	
	static int sTabCount = 0;
	
	// these are option menu IDs
	private static final int ADD_LINE_COMMENT	= Menu.FIRST;
	private static final int ADD_BLOCK_COMMENT	= Menu.FIRST+1;
	private static final int ADD_SEMICOLON		= Menu.FIRST+2;
	private static final int ADD_BRACE			= Menu.FIRST+3;
	private static final int ADD_BRACKET		= Menu.FIRST+4;
	private static final int ADD_TAB			= Menu.FIRST+5;
		
	/* Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // get window feature for shwoing progress bar
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
                
        // get system service to control soft keyboard
        iputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);  
        /* setting tabs */
        mTabHost = getTabHost();
        // Show this app_name and filename to app title.
        mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener()
		{
			@Override
			public void onTabChanged(String tabId)
			{
				// TODO Auto-generated method stub				
				setTitle(getResources().getText(R.string.app_name)+ " - " + tabId);				
				
			}
		});
                
        
        mSourceView = new HashMap<String, View>();
        
        LayoutInflater.from(this).inflate(R.layout.main, mTabHost.getTabContentView(), true);
          
        /* When app begin, show '+' tab only.*/
        createTabAndSourceView("+");        
        createTabAndSourceView("SourceView.java");
        createTabAndSourceView("Setting.java");
//        createTabAndSourceView("EditorActivity.java");                
        
        // turn on progress bar on title
        setProgressBarIndeterminateVisibility(true);
      }  
    
	/**
     * create Tab and SourceView
     * @param filename : If selecting New-menu, put "*" instead of filename.
     * 					 If selecting Open-menu, put filename.
     * */
    public void createTabAndSourceView(String filename)
    {
    	mSourceView.put(filename, createSourceView(filename));
       	mTabHost.addTab(createTab(filename)); 
     }
    
    /**
     * create new tab (Tab label is tag.)
     * @param tag : If selecting New-menu, put "*" instead of filename.
     * 				If selecting Open-menu, put filename.
     * */
    public TabSpec createTab(String tag)
    {	
    	return	mTabHost.newTabSpec(tag)
    			.setIndicator(createIndicatorViewOnlyLabel(tag))
    			.setContent(this);
    }
	
	/** 
	 * Create tab widget only label without icon.
	 * 
	 * @param label If selecting New-menu, put "*" instead of filename.
     * 				If selecting Open-menu, put filename.
	 * @return tab widget only label
	 */
	public View createIndicatorViewOnlyLabel(String label) 
	{		
		// create TextView for label
		TextView tv = new TextView(this);		
		tv.setGravity(Gravity.CENTER);						// set on center
		tv.setText(label);									// set text of label
		tv.setSingleLine(true);
		tv.setEllipsize(TextUtils.TruncateAt.MARQUEE);		
		tv.setMarqueeRepeatLimit(-1);						// set marquee repeats unlimited
		tv.setBackgroundResource(R.drawable.tab_indicator);	// set tab image
		
        // If Android version 1.6 of your device, show other tab image.
        if (this.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT)
        {
            // Donut apps get old color scheme
            tv.setBackgroundResource(R.drawable.tab_indicator_v4);
            tv.setTextColor(this.getResources().getColorStateList(R.color.tab_indicator_text_v4));
        }
        
        tv.setOnLongClickListener(new OnLongClickListener() {
			
			@Override
			public boolean onLongClick(View v) {
				String fileName = ((TextView) v).getText().toString();
//				((SourceView) mSourceView.get(fileName)).tabCount = mTabCount;
				((SourceView) mSourceView.get(fileName)).controlTabMenu();
				Log.d("xxxxxxxxxxxxxxxxxxxxxx", " long clicked!!!!!!!!!!!");
				return false;
			}
		});
        
        return tv;
    }
	
	/**
	 * Create new sourceView.
	 * 
	 * @param filename If selecting New-menu, put "*" instead of filename.
     * 				   If selecting Open-menu, put filename.
     * @return EditText and first screen is TextView for title.
	 * */
	public View createSourceView(String filename)
	{
		View v;
		// create titleView
		if(mSourceView.isEmpty())
		{			
			v = (TextView)findViewById(R.id.title_view);
		}
		
		// create sourceView
		else
		{									
			v = new SourceView(this);			
			// pass 'iputMethodManager' to sourceView to let sourceView can handle soft keyboard
			((SourceView) v).setInputMethodManager(iputMethodManager);
			((SourceView) v).setFileName(filename);
			((SourceView) v).setSource();
			((SourceView) v).getNewSouceView().setInitialKeyWordFilter();	
			updateTabCount();
			((SourceView) v).tabNumber = sTabCount;
		}
		return v;
	}	
	
	public void updateTabCount(){
		sTabCount = mTabHost.getTabWidget().getChildCount();		
		
//		((SourceView)mSourceView.get(mTabHost.getCurrentTabTag())).TabCount
	}
	
	/**
	 * Connect sourceView to a tab.
	 * 
	 * @param tag The tag of a tab or the filename.
	 * @return SourceView that will connect to tab. 
	 * */
	@Override
	public View createTabContent(String tag)
	{
		return mSourceView.get(tag);
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		
		MenuItem itemAddLineComment		= menu.add(0, ADD_LINE_COMMENT, Menu.NONE, R.string.option_line_comment);
		MenuItem itemAddBlockComment 	= menu.add(0, ADD_BLOCK_COMMENT, Menu.NONE, R.string.option_block_comment);
		MenuItem itemAddSemicolon 		= menu.add(0, ADD_SEMICOLON, Menu.NONE, R.string.option_semicolon);
		MenuItem itemAddBrace 			= menu.add(0, ADD_BRACE, Menu.NONE, R.string.option_brace);
		MenuItem itemAddBracket 		= menu.add(0, ADD_BRACKET, Menu.NONE, R.string.option_bracket);
		MenuItem itemAddTab 			= menu.add(0, ADD_TAB, Menu.NONE, R.string.option_tab);
		return true;
	}
	
	/* if user in the first tab, hide entire option menu */
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		super.onPrepareOptionsMenu(menu);

		if(mTabHost.getCurrentTabTag() == "+"){
			menu.setGroupVisible(0, false);
		}
		else{
			menu.setGroupVisible(0, true);
		}		
		return true;
	}
	
	/*  */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		super.onOptionsItemSelected(item);
				
		SourceView currentSourceView = (SourceView) mSourceView.get(mTabHost.getCurrentTabTag());
		Editable currentSourceViewEditable = currentSourceView.getNewSouceView().getText();
		
		int cursor = currentSourceView.getNewSouceView().getSelectionStart();
		int lineEnd = currentSourceView.getNewSouceView().getCurrentLineEnd(); 
						
		switch(item.getItemId()){
			case (ADD_LINE_COMMENT) : {
				addLineCommentToSourceView(currentSourceViewEditable, cursor, lineEnd);
				return true;
			}
			case (ADD_BLOCK_COMMENT) : {
				addBlockCommentToSourceView(currentSourceViewEditable, cursor);
				return true;
			}
			
			case (ADD_SEMICOLON) : {
				addSemicolonToSourceView(currentSourceViewEditable, cursor);
				return true;
			}
			case (ADD_BRACE) : {
				addBraceToSourceView(currentSourceViewEditable, cursor);
				return true;
			}
			case (ADD_BRACKET) : {
				addBracketToSourceView(currentSourceViewEditable, cursor);
				return true;
			}
			case (ADD_TAB) : {
				addTabToSourceView(currentSourceViewEditable, cursor);
				return true;
			}			
		}		
		return false;
	}
	
	/* insert tab to source */
	private void addTabToSourceView(Editable currentSourceViewEditable,int cursor) {
		currentSourceViewEditable.insert(cursor, "\t");		
	}
	
	/* insert bracket to source and locate cursor between them */
	private void addBracketToSourceView(Editable currentSourceViewEditable,int cursor) {
		currentSourceViewEditable.insert(cursor, "()");
		Selection.setSelection(currentSourceViewEditable, cursor+1);
	}

	/* insert brace to source and locate cursor between them */
	private void addBraceToSourceView(Editable currentSourceViewEditable,int cursor) {
		currentSourceViewEditable.insert(cursor, "{}");
		Selection.setSelection(currentSourceViewEditable, cursor+1);
	}

	/* insert block comment to source and locate cursor between them */
	private void addBlockCommentToSourceView(Editable currentSourceViewEditable, int cursor) {
		currentSourceViewEditable.insert(cursor, "/**/");
		currentSourceViewEditable.setSpan(new ForegroundColorSpan(Color.GREEN), cursor, cursor+4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		Selection.setSelection(currentSourceViewEditable, cursor+2);		
	}

	/* insert line comment to source and change color to green behind comment */
	private void addLineCommentToSourceView(Editable currentSourceViewEditable, int cursor, int lineEnd) {		
		currentSourceViewEditable.insert(cursor, "//");		
		currentSourceViewEditable.setSpan(new ForegroundColorSpan(Color.GREEN), cursor, lineEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
	}

	/* insert semicolon to source */
	private void addSemicolonToSourceView(Editable currentSourceViewEditable, int cursor) {				
		currentSourceViewEditable.insert(cursor, ";");
	}
	
}